#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <SDL/SDL.h>

#include "zombies.h"
#include "monsters.h"
#include "victims.h"
#include "items.h"
#include "level.h"
#include "display.h"
#include "gfx.h"

// global scope
unsigned char *romdata;
state_t st;

unsigned int ROMToFile(unsigned int dwOffset)
{
	unsigned int addr, bank, file;

	addr = dwOffset % 0x8000;
	bank = (dwOffset >> 16) - 0x80;
	file = bank * 0x8000;
	file = (file | addr) + 0x200;

	return file;
}

void saverom()
{
    FILE *rom;

    if(1)
    {
        unsigned int offset;

        offset=BASE_PTR+level.monster_ptr;
        memcpy(romdata+offset,&rmonsters,sizeof(monster_t)*rmonstercount);

        offset=BASE_PTR+level.victim_ptr;
        memcpy(romdata+offset,&victims,sizeof(victim_t)*MAX_VICTIMS);

        offset=BASE_PTR+level.item_ptr;
        memcpy(romdata+offset,&items,sizeof(item_t)*itemcount);
        
        offset=ROMToFile(level.mapoffset);
        memcpy(romdata+offset,mapdata,mapsize);
    }

    rom=fopen("test.smc","wb");
    fwrite(romdata,st.romsize,1,rom);
    fclose(rom);
}

void loadrom()
{
    FILE *rom;

    rom=fopen("zombies.smc","r");
 
    fseek(rom,0,SEEK_END);
    st.romsize=ftell(rom);
    fseek(rom,0,SEEK_SET);

    romdata=(unsigned char *)malloc(st.romsize);
    fread(romdata,st.romsize,1,rom);
    fclose(rom);
}

void dumpinfo()
{
    int c;

    extern victim_t fmonsters[MAX_MONSTERS];

    printf("Level ptr: 0x%02x\n",ROMToFile(level.mapoffset));
    printf("Title1 ptr: 0x%02x\n",BASE_PTR+level.title1_ptr);
    printf("Map dimensions: %d x %d\n",level.width,level.height);
    printf("Map size: %d bytes\n",mapsize);
    printf("monster_ptr: 0x%02x, victim_ptr: 0x%02x, item_ptr: 0x%02x\n",level.monster_ptr,level.victim_ptr,level.item_ptr);
    printf("Number of level items: %d\n",itemcount);
    printf("Respawn Monsters: %d\n",rmonstercount);
    printf("Fixed Monsters: %d\n",fmonstercount);

    // print items positions and types
    for(c=0;c<MAX_ITEMS;c++)
    {
        if(!items[c].x && !items[c].y)
            break;

        printf("Item number: %02x | Position x: %04d, y: %04d | Code: 0x%02x\n",c,items[c].x,items[c].y,items[c].code);
    }

    // print monsters positions and types
    for(c=0;c<MAX_MONSTERS;c++)
    {
        if(!rmonsters[c].x && !rmonsters[c].y)
            break;

        printf("Respawn Monster number: %02x | Position x: %04d, y: %04d | Type: 0x%02x (%s)\n",c,rmonsters[c].x,rmonsters[c].y,rmonsters[c].code,getmonstername(rmonsters[c].code));
    }

    // print monsters positions and types
    for(c=0;c<MAX_MONSTERS;c++)
    {
        if(!fmonsters[c].x && !fmonsters[c].y)
            break;

        printf("One Time Monster number: %02x | Position x: %04d, y: %04d | Type: 0x%02x (%s)\n",c,fmonsters[c].x,fmonsters[c].y,fmonsters[c].code,getmonstername(fmonsters[c].code));
    }

    // print victim positions and types
    for(c=0;c<MAX_VICTIMS;c++)
    {
        if(!victims[c].x && !victims[c].y)
            break;

        printf("Victim number: %02x | Position x: %04d, y: %04d | Type: 0x%02x (%s)\n",victims[c].number,victims[c].x,victims[c].y,victims[c].code,getvictimname(victims[c].code));
    }
}

int main(int argc, char *argv[])
{
    if(argc<2)
    {
        printf("No level given.\n");
        exit(0);
    }

    atexit(SDL_Quit);

    //Initialize all SDL subsystems
    if(SDL_Init(SDL_INIT_EVERYTHING)==-1)
    {
        return 0;
    }

    st.quit=0;
    st.bgedit=0;
    st.showgrid=0;
    st.showitems=1;
    st.showmonsters=1;
    st.showvictims=1;
    st.showclipboard=1;
    st.cbpos=0;

    st.currentlevel=atoi(argv[1]);

    // load rom into memory buffer
    loadrom();

    // read rom stuff
    readlevel(st.currentlevel);
    readmap();
    readitems();
    readmonsters();
    readvictims();
    dumpinfo();

    loadgraphics();

    initdisplay();

    while(!st.quit)
    {
        mainloop();
    }
}
